/*
 *  This file was originally created by Ireneusz Grala on 29th of December 2010
 *  e-mail: ireneusz.grala@wp.pl
 *  
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Samples.Location;
using SimpleGPSApp.Base;

namespace SimpleGPSApp.Controls
{
    public partial class SatellitesSignalPosition : UserControl
    {

        #region Fields
        
        #region Signal 
        private int startY = 5;
        private int signalBarHeight = 40;
        private int signalBarWidth = 10;
        #endregion

        #region Position in space
        private int outerCircleRadius = 60;
        private int outerCircleDiameter = 0;
        private int satelliteRadius = 0;
        private int outerCircleRectX = 80;
        private int outerCircleRectY = 84;
        private int circlesRadiusStep = 20;
        private int doubledRadiusStep = 0;
        private int middleCircleDiameter = 0;
        private int innerCircleDiameter = 0;
        private int centerX = 0;
        private int centerY = 0;
        #endregion
        GpsPosition position = null;
        #endregion


        #region Properties
        public GpsPosition Position
        {
            set 
            { 
                position = value;
                if (position != null)
                    this.Refresh();
            }
        }
        #endregion

        public SatellitesSignalPosition()
        {
            InitializeComponent();
            outerCircleDiameter = 2 * outerCircleRadius;
            
            doubledRadiusStep = 2 * circlesRadiusStep;
            middleCircleDiameter = outerCircleDiameter - doubledRadiusStep;
            
            innerCircleDiameter = outerCircleDiameter -  middleCircleDiameter;
            
            centerX = outerCircleRectX + outerCircleRadius;
            centerY = outerCircleRectY + outerCircleRadius;
            satelliteRadius = doubledRadiusStep;

            //DrawSpaceMap(CreateGraphics());
        }


        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.Clear(this.BackColor);
            DrawSignalStrength(e.Graphics);
            DrawSpaceMap(e.Graphics);
            DrawSatellites(e.Graphics);
            
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //base.OnPaintBackground(e);
        }

        #region Satellites position drawing methods
        private void DrawSpaceMap(Graphics g)
        {

            g.DrawEllipse(new Pen(Color.Green), new Rectangle(outerCircleRectX + doubledRadiusStep, outerCircleRectY + doubledRadiusStep, innerCircleDiameter, innerCircleDiameter)); // inner circle
            g.DrawEllipse(new Pen(Color.Green), new Rectangle(outerCircleRectX + circlesRadiusStep, outerCircleRectY + circlesRadiusStep, middleCircleDiameter, middleCircleDiameter)); // middle circle
            g.DrawEllipse(new Pen(Color.Green), new Rectangle(outerCircleRectX, outerCircleRectY, outerCircleDiameter, outerCircleDiameter )); // outer circle
            g.DrawLine(new Pen(Color.Green), outerCircleRectX, centerY, outerCircleRectX + outerCircleDiameter, centerY); // horizontal line
            g.DrawLine(new Pen(Color.Green), centerX, outerCircleRectY, centerX, outerCircleRectY + outerCircleDiameter); // vertical line
            g.DrawLine(new Pen(Color.Green), (outerCircleRectX + 15), (outerCircleRectY + outerCircleDiameter - 15), (outerCircleRectX + outerCircleDiameter - 15), (outerCircleRectY + 15) ); // diagonal
            g.DrawLine(new Pen(Color.Green), (outerCircleRectX + 15), (outerCircleRectY + 15), (outerCircleRectX + outerCircleDiameter - 15), (outerCircleRectY + outerCircleDiameter - 15) ); // diagonal

            g.DrawString("N", new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Green), centerX - 2, outerCircleRectY - 16);
            g.DrawString("E", new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Green), outerCircleRectX + outerCircleDiameter + 8, centerY - 7);
            g.DrawString("S", new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Green), centerX - 2, outerCircleRectY + outerCircleDiameter + 4);
            g.DrawString("W", new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Green), outerCircleRectX - 14, centerY - 7);
        }

        // satellites drawing space
        private void DrawSatellites(Graphics g)
        {
            if (position != null)
            {
                foreach (Satellite sat in position.GetSatellitesInSolution())
                {
                    double azimuthInRadians = (sat.Azimuth * Math.PI) / 180;
                    int x = (int)(satelliteRadius * Math.Cos(azimuthInRadians));
                    int y = (int)(satelliteRadius * Math.Sin(azimuthInRadians));
                    x += centerX;
                    y += centerY;

                    if (Satellites.SatelliteIsInSolution(position, sat))
                    {
                        g.FillRectangle(new SolidBrush(Color.Green), new Rectangle(x, y, 5, 5));
                        g.DrawString(sat.Id.ToString(), new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Green), x, y + 5);
                    }
                    else
                    {
                        g.FillRectangle(new SolidBrush(Color.Red), new Rectangle(x, y, 5, 5));
                        g.DrawString(sat.Id.ToString(), new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Red), x, y + 5);
                    }
                }
            }
        }
        #endregion


        #region Satellites signal strengh methods
        private void DrawSignalStrength(Graphics g)
        {
            if (position != null)
            {
                try
                {
                    Satellite[] satArray = position.GetSatellitesInView();
                    for (int i = 0; i < satArray.Length; i++)
                    {
                        int x = (signalBarWidth + 5) * i + signalBarWidth;

                        g.DrawRectangle(new Pen(Color.Black), new Rectangle(x, startY, signalBarWidth, signalBarHeight));

                        if (Satellites.SatelliteIsInSolution(position, satArray[i]))
                            DrawSignalBar(g, x, startY + signalBarHeight - satArray[i].SignalStrength, satArray[i], true);
                        else
                            DrawSignalBar(g, x, startY + signalBarHeight - satArray[i].SignalStrength, satArray[i], false);

                        g.DrawString(satArray[i].Id.ToString(), new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Black), x, startY + signalBarHeight + 3);
                    }
                }
                catch (Exception e)
                {
                    IRQBaseFunctions.ErrorLog.WriteError(Base.Config.ErrorLogFileName, "DrawSignalStrength: " + e.ToString());
                }
            }
            else
            {
                for (int i = 0; i < 10; i++)
                {
                    int x = (signalBarWidth + 5) * i + signalBarWidth;
                    DrawEmptySignalBar(g, x, startY);
                }
            }
        }

        private void DrawSignalBar(Graphics g, int x, int y, Satellite sat, bool satelliteInUse)
        {
            if (satelliteInUse)
                g.FillRectangle(new SolidBrush(Color.Green), new Rectangle(x + 1, y, signalBarWidth - 1, sat.SignalStrength));
            else
                g.FillRectangle(new SolidBrush(Color.Red), new Rectangle(x + 1, y, signalBarWidth - 1, sat.SignalStrength));
        }

        private void DrawEmptySignalBar(Graphics g, int x, int y)
        {
            g.DrawRectangle(new Pen(Color.Black), new Rectangle(x, y, signalBarWidth, signalBarHeight));
            g.DrawString("0", new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Regular), new SolidBrush(Color.Black), x + 4, y + signalBarHeight + 3);
        }
        #endregion
    }
}
